function XMBridge() {
  console.log('bridge');
}

XMBridge.prototype.request = function request(name, param) {
  console.log(name);
  console.log(param);
};

function bind(fn, thisArg) {
  return function wrap() {
    // eslint-disable-next-line prefer-rest-params
    return fn.apply(thisArg, arguments);
  };
}

function isArray(val) {
  return Array.isArray(val);
}

function forEach(obj, fn) {
  // Don't bother if no value provided
  if (obj === null || typeof obj === 'undefined') {
    return;
  }

  // Force an array if not already something iterable
  if (typeof obj !== 'object') {
    /* eslint no-param-reassign:0 */
    obj = [obj];
  }

  if (isArray(obj)) {
    // Iterate over array values
    for (let i = 0, l = obj.length; i < l; i++) {
      // eslint-disable-next-line no-useless-call
      fn.call(null, obj[i], i, obj);
    }
  } else {
    // Iterate over object keys
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        // eslint-disable-next-line no-useless-call
        fn.call(null, obj[key], key, obj);
      }
    }
  }
}

function extend(a, b, thisArg) {
  forEach(b, function assignValue(val, key) {
    if (thisArg && typeof val === 'function') {
      a[key] = bind(val, thisArg);
    } else {
      a[key] = val;
    }
  });
  return a;
}

function createInstance() {
  const context = new XMBridge();
  const instance = bind(XMBridge.prototype.request, context);
  extend(instance, XMBridge.prototype, context);
  extend(instance, context);
  instance.create = function create() {
    return createInstance();
  };
  return instance;
}

const xmNew = createInstance();
xmNew.XMBridge = XMBridge;

export default xmNew;
